﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Toolkit.Web.ExtensionMethods;

namespace Toolkit.Web.ViewComponents.WebAssetRegistrar
{
    public class WebAssetCollection : Collection<IWebAsset>
    {
        public WebAssetCollection()
        {
        }

        public IEnumerable<WebAssetGroup> AssetGroups
        {
            get
            {
                return this.OfType<WebAssetGroup>();
            }
        }

        public IEnumerable<WebAsset> AssetItems
        {
            get
            {
                return this.OfType<WebAsset>();
            }
        }

        public WebAssetGroup FindGroupByName(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("name");
            }

            return AssetGroups.SingleOrDefault(group => group.Name.IsCaseInsensitiveEqual(name));
        }

        public WebAsset FindItemBySource(string source)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException("source");
            }

            return AssetItems.SingleOrDefault(group => group.Source.IsCaseInsensitiveEqual(source));
        }

        public void Add(string source)
        {
            base.Add(CreateItem(source));
        }

        public void Add(string groupName, string source)
        {
            WebAssetGroup itemGroup = FindGroupByName(groupName);

            if (itemGroup == null)
            {
                itemGroup = CreateGroup(groupName);
                base.Add(itemGroup);
            }

            itemGroup.Items.Add(CreateItem(source));
        }

        public void Insert(int index, string source)
        {
            base.Insert(index, CreateItem(source));
        }

        public void Insert(int index, string groupName, string source)
        {
            WebAssetGroup itemGroup = FindGroupByName(groupName);

            if (itemGroup == null)
            {
                itemGroup = CreateGroup(groupName);
                base.Insert(index, itemGroup);
            }

            itemGroup.Items.Add(CreateItem(source));
        }

        protected override void InsertItem(int index, IWebAsset item)
        {
            if (!AlreadyExists(item))
            {
                base.InsertItem(index, item);
            }
        }

        private WebAssetGroup CreateGroup(string name)
        {
            return new WebAssetGroup(name, false);
        }

        private WebAsset CreateItem(string source)
        {
            return new WebAsset(source);
        }

        private bool AlreadyExists(IWebAsset item)
        {
            WebAsset assetItem = item as WebAsset;
            WebAssetGroup assetItemGroup = item as WebAssetGroup;

            if (assetItem != null)
            {
                return AssetItems.Any(i => i != item && i.Source.IsCaseInsensitiveEqual(assetItem.Source));
            }

            if (assetItemGroup != null)
            {
                return AssetGroups.Any(i => i != item && i.Name.IsCaseInsensitiveEqual(assetItemGroup.Name));
            }

            return false;
        }
    }
}
